#include "counterthread.h"

using namespace XVL;

CounterThread::CounterThread(QObject *parent)
    : QThread{parent}
    , stopRequested_(false)
    , isReceived_(false)
    , countMode_(0)
    , totalLimit_(30)
    , leftLimit_(20)
    , rightLimit_(20)
    , totalCount_(0)
    , leftCount_(0)
    , rightCount_(0)
{}

CounterThread::~CounterThread()
{

}

void CounterThread::resetCounts()
{
    totalCount_ = 0;
    leftCount_ = 0;
    rightCount_ = 0;
}

void CounterThread::resetstopFlag()
{
    stopRequested_.store(false);
}

void CounterThread::stopProcessing()
{
    stopRequested_.store(true);
    waitCondition_.wakeAll();
}

void CounterThread::setCountMode(int mode)
{
    countMode_ = mode;
}

void CounterThread::setLimits(int totalLimit, int leftLimit, int rightLimit)
{
    totalLimit_ = totalLimit;
    leftLimit_ = leftLimit;
    rightLimit_ = rightLimit;
}

bool CounterThread::shouldStop()
{
    return stopRequested_.load();
}

void CounterThread::checkAndWaitReceived()
{
    while (!isReceived_.load() && !shouldStop())
    {
        QMutexLocker locker(&mutex_);
        waitCondition_.wait(&mutex_, 500);
    }
    isReceived_.store(false);
}

void CounterThread::run()
{
    // 重置停止标志
    resetstopFlag();
    // 循环执行
    while(!shouldStop())
    {
        // 检查并等待是否收到处理线程的信号
        checkAndWaitReceived();
        // 检查是否退出
        if (shouldStop())
        {
            break;
        }
        // 在检查超限前发送计数更新信号
        CountResult result;
        result.totalCount = totalCount_;
        result.leftCount = leftCount_;
        result.rightCount = rightCount_;
        emit countUpdated(result);
        // 检查是否超过上限
        if (checkLimits(totalCount_, leftCount_, rightCount_))
        {
            // 发出超过上限信号，所有线程暂停2秒
            emit limitExceeded();
            // 重置超过上限的计数
            if (countMode_ == 0)
            {
                totalCount_ = 0;
            }
            else
            {
                if (leftCount_ > leftLimit_)
                {
                    leftCount_ = 0;
                }
                if (rightCount_ > rightLimit_)
                {
                    rightCount_ = 0;
                }
            }
        }
    }
}

void CounterThread::calcuLeftRightCount(const int width, const vector<XVL::XVRegion> &regions)
{
    // 计算图像中间分割线的X坐标
    float midX = width / 2.0;

    int leftCount = 0;  // 左侧区域数量
    int rightCount = 0; // 右侧区域数量

    int res = 0;        // 运行结果返回值
    // 遍历所有分割区域
    for (const auto& subRegion : regions)
    {
        // 通过区域外接框的左上角和右上角的x坐标比较
        XVRegionBoundingBoxIn boxIn;
        boxIn.inRegion = subRegion;
        XVRegionBoundingBoxOut boxOut;
        res = XVRegionBoundingBox(boxIn, boxOut);
        if(res != 0)
        {
            continue;
        }

        float leftX = boxOut.outLeftUp.x;
        float rightX = boxOut.outRightUp.x;

        if(leftX > midX)
        {
            rightCount++;
        }
        else if(rightX < midX)
        {
            leftCount++;
        }
        else
        {
            // 进入else表示分割的区域在中间分割线上，计算质心
            XVRegionCenterIn centerIn;
            centerIn.inRegion = subRegion;
            XVRegionCenterOut centerOut;
            res = XVRegionCenter(centerIn, centerOut);
            if(res != 0)
            {
                continue;
            }

            if(centerOut.outCenter.x < midX)
            {
                leftCount++;
            }
            else
            {
                rightCount++;
            }
        }
    }
    leftCount_ += leftCount;
    rightCount_ += rightCount;
}

bool CounterThread::checkLimits(int totalCount, int leftCount, int rightCount)
{
    if (countMode_ == 0)
    {
        return totalCount > totalLimit_;
    }
    else
    {
        return (leftCount > leftLimit_) || (rightCount > rightLimit_);
    }
}

void CounterThread::onRegionsReceived(const int width, const vector<XVL::XVRegion>& regions)
{
    if (countMode_ == 0)
    {
        totalCount_ += static_cast<int>(regions.size());
    }
    else
    {
        calcuLeftRightCount(width, regions);
    }
    {
        QMutexLocker locker(&mutex_);
        isReceived_.store(true);
    }
    waitCondition_.wakeOne();
}
